#include "StdAfx.h"
#include "XmlDocument.h"

namespace System{
namespace Xml{

VIRTUAL_GET_TYPE_IMPLEMENT(System::Xml::XmlDocument, System_Xml_XmlDocument)
VIRTUAL_TOSTRING_IMPLEMENT(System::Xml::XmlDocument, System_Xml_XmlDocument)

XmlDocument::XmlDocument(void)
{
}


XmlDocument::~XmlDocument(void)
{
}


void XmlDocument::LoadXml(const PTSTR xmlStr)
{
	for(PTSTR xml = xmlStr; *xml != 0; xml++)
	{
		switch(*xml)
		{
			case '<':
				if(*(xml + 1) == '?') {
					this->ParseProlog(xml);
				} else if(*(xml + 1) == '!') {
					this->SkipComment(&xml);
				} else {
					this->ParseElement(&xml);
				}
				break;
		}
	}

}


void XmlDocument::ParseProlog(PTSTR xml)
{
}

void XmlDocument::ParseElement(PPTSTR xml)
{
	if(**xml == '<')
	{
		XmlElement* element = NULL;
		PTSTR start = PPTSTR_SKIP(xml, 1);

		size_t len = ParseName(&*xml);
		if(len > 0)
		{
			PPTSTR_SKIP(xml, len);

			element = new XmlElement(start, len);
			this->m_Elements.Add(element);
		}

		for(; **xml != 0; len++)
		{
			switch(**xml)
			{
				case ' ':
					break;

				case '/':
					break;

				case '>':
					break;

				default:

					break;
			}
		}

	}

}

void XmlDocument::BeginElement(PPTSTR xml)
{
	


}

void XmlDocument::ParseAttribute(PPTSTR xml)
{
	
}

void XmlDocument::ParseAttributeValue(PPTSTR xml)
{
	
}


void XmlDocument::ParseStartTag(PPTSTR xml)
{

}

void XmlDocument::ParseEndTag(PPTSTR xml)
{

}

void XmlDocument::EmptyElementTag(PPTSTR xml)
{

}


size_t XmlDocument::ParseName(PPTSTR xml)
{
	size_t len = 0;

	for(; *(*xml + len) != 0; len++)
	{
		if(len == 0) {
			if(!IsNameStartChar(*(*xml + len)))
			{
				break;
			}
		} else if(IsNameChar(*(*xml + len))) {
			continue;
		} else {
			break;
		}
	}

	return len;
}



void XmlDocument::SkipComment(PPTSTR xml)
{
	if(**xml == '<' && *(*xml + 1) == '!' && *(*xml + 2) == '-' && *(*xml + 3) == '-')
	{
		PPTSTR_SKIP(xml, 4);
		for(;**xml != 0; PPTSTR_SKIP(xml, 1))
		{
			if(**xml == '-')
			{
				if(**xml == '-' && *(*xml + 1) == '-' && *(*xml + 2) == '>')
				{
					PPTSTR_SKIP(xml, 3);
					return;
				} else if(**xml == '-' && *(*xml + 1) == '-') {
					throw new ParseXmlException();
				}
			}
		}
	}
}













bool XmlDocument::IsNameStartChar(TCHAR ch)
{
	return  (ch == ':') || (ch == '_')     || (ch >= 'A' && ch <= 'Z')       || (ch >= 'a' && ch <= 'z')        ||
			(ch >= 0XC0   && ch <= 0XD6)   || (ch >= 0XD8   && ch <= 0XF6)   || (ch >= 0XF8    && ch <= 0X2FF)  ||
			(ch >= 0X370  && ch <= 0X37D)  || (ch >= 0x37F  && ch <= 0x1FFF) || (ch >= 0x200C  && ch <= 0x200D) ||
			(ch >= 0x2070 && ch <= 0x218F) || (ch >= 0x2C00 && ch <= 0x2FEF) || (ch >= 0x3001  && ch <=0xD7FF)  || 
			(ch >= 0xF900 && ch <= 0xFDCF) || (ch >= 0xFDF0 && ch <= 0xFFFD) || (ch >= 0x10000 && ch <= 0xEFFFF);
}

bool XmlDocument::IsNameChar(TCHAR ch)
{
	return  IsNameStartChar(ch) || (ch == '-') || (ch == '.') || (ch >= '0' && ch <= '9') || (ch == 0XB7) || (ch >= 0X0300  && ch <= 0X036F) || (ch >= 0X203F && ch <= 0X2040);
}

bool XmlDocument::IsWhiteSpace(TCHAR ch)
{
	//space characters, carriage returns, line feeds, or tabs
	return (ch == 0X20 || ch == 0X9 || ch == 0XD || ch ==0XA);
}




}
}